#pragma once

#include<iostream>
#include<queue>
#include<pthread.h>
#include"task.hpp"

using namespace std;

#define NUM 6

class ThreadPool{

public:

    static ThreadPool* GetInstand(){
        static pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;
        if(nullptr==_inst){
            pthread_mutex_lock(&mtx);
            if(_inst==nullptr){
                _inst=new ThreadPool();
                _inst->InitThreadPool();
            }
            pthread_mutex_unlock(&mtx);

        }

        return _inst;
    }

    static void* ThreadRoutie(void *args){
        pthread_detach(pthread_self());

        ThreadPool*tp=(ThreadPool*)args;
        while(1){
            pthread_mutex_lock(&(tp->_lock));
            while(tp->_task_queue.empty()){
                pthread_cond_wait(&(tp->_cond),&(tp->_lock));

            }
            Task task=tp->_task_queue.front();
            tp->_task_queue.pop();
            pthread_mutex_unlock(&(tp->_lock));

            cout<<"准备开始执行任务"<<endl;
            task.ProcessOn();
        }


    }

    void PushTask(const Task _task){
        cout<<"push了新任务,开始抢锁"<<endl;
        pthread_mutex_lock(&_lock);
        cout<<"线程池push了一个任务"<<endl;
        _task_queue.push(_task);
        pthread_mutex_unlock(&_lock);
        pthread_cond_signal(&_cond);
    }

    void InitThreadPool(){

        pthread_t tid;
        for(int i=0;i<NUM;i++){
            pthread_create(&tid,nullptr,ThreadRoutie,this);
        }
    }

    ~ThreadPool(){
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }



private:
    queue<Task> _task_queue;

    pthread_mutex_t _lock;
    pthread_cond_t _cond;
    static ThreadPool * _inst;

    

    ThreadPool(int num=NUM){
        pthread_mutex_init(&_lock,nullptr);
        pthread_cond_init(&_cond,nullptr);
    }

    ThreadPool(const ThreadPool&)=delete;
    ThreadPool operator=(const ThreadPool)=delete;
};

ThreadPool*ThreadPool::_inst=nullptr;